今天介紹簡單的 Buffer Overflow 題目。
Buffer Overflow 是什麼?
根據Wiki:
(Buffer Overflow) 緩衝區溢位,是針對程式
設計缺陷
,向程式輸入緩衝區寫入使之溢位的內容,從而破壞程式執行、趁著中斷之際並取得程式乃至系統的控制權。 緩衝區溢位原指當某個資料超過了處理程式回傳堆疊位址限制的範圍
時,程式出現的異常操作。造成此現象的原因有: 存在缺陷的程式設計。
將檔案丟進 Hopper disassembler 進行逆向。
已知檔案類型:
$ file ./bin
./bin: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.24, BuildID[sha1]=0148298bc390fe9db9f72b2b26dd650360c7eec2, with debug_info, not stripped
透過反組譯,看到它使用危險函數 scanf()
[因為 scanf()不會檢查使用者輸入時的邊界,因而導致使用者的輸入過長蓋過程式的記憶體位置,可能導致程式出現非預期的行為],因此大膽猜測這題想考 Buffer Overflow。開始測試輸入:
執行 ./bin
發現驗證需要是 admin 才會通過驗證。
輸入換成 admin 試試看,也還是不行:
試試看輸入改成 aaabbbcccddddeeefff,發現有趣的事情,admin 被改掉了。透過輸入的字串得知 admin 的位置在 aaabbbccadmin
。
輸入改成 aaabbbccadmin
,成功通關!
更快的方法:繞過 test eax, eax
因為 test eax, eax 等同以下:
if(eax == 0)
{
goto some_address
}
Why? 因為 test eax, eax 等同 AND eax, eax 。 若其 bitwise 操作要回傳 0 的話(因為目標是 je),eax 必需為 0。舉例來說,若 eax = 0x2(0010[2]),則在 AND eax, eax 等於 0010 AND 0010 ,無論如何都不會回傳0。因此唯有 eax = 0時
,0 AND 0 才會等於 0, test 才會將 ZF (zero flag)設置為1,才能觸發 jz 到我們想去的程式。
因此可以直接更改 eax 的數值,將其改成 0 即可跳到 loc_804853c
(原本 eax 是 0x1[如下圖],將其改成0)
改法:set $eax = 0
即可繞過
今天介紹 Buffer Overflow,明天接著介紹如何提升程式被逆向的成本?